package digitRecognitionProblem.learnWeights;

import genetic_algorithm.Chromosome;
import genetic_algorithm.FitnessFunction;

import java.util.ArrayList;
import java.util.Map.Entry;

import mlp.Mlp;
import mlp.UniformTrainExamples;
import utils.RandomGenerator;
import digitRecognitionProblem.DigitRecognitionMlpFitness;

/**
 * A chromosome's fitness is calculated by training its network for a single
 * epoch and then evaluating its success rate on the test set
 */
public class Lwfitness implements FitnessFunction {
	
	private UniformTrainExamples trainExamples; // examples used to train networks generated out of chromosomes
	private Entry<ArrayList<float[]>,ArrayList<float[]>> trainData;
	
	/**
	 * Constructor- creates a new object to evaluate
	 * chromosome's fitness
	 */
	public Lwfitness() {
		
		super();		
		this.trainExamples = new UniformTrainExamples("train_reduce.csv", LWmain.DIGIT);
	}
	
	/**
	 * Calculates chromosome's fitness according to its
	 * neural network mean squared error 
	 */
	@Override
	public double getFitness(Chromosome chromosome) {
		
		int offset = RandomGenerator.nextInt(38000 / 400);
		trainData = trainExamples.getExamples(offset, 400);
		Mlp mlp = ((LWchromosome) chromosome).getMlp();
		mlp.learn(trainData.getKey(), trainData.getValue(), 1);
				
		((LWchromosome) chromosome).setMlp(mlp);
		
		DigitRecognitionMlpFitness funcFit = new DigitRecognitionMlpFitness(((LWchromosome)chromosome).getMlp());		
		return funcFit.getFitness(null);
	}
}
